package com.example.a_java.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.a_java.dto.LendingApplyDTO;
import com.example.a_java.dto.LendingDetailVO;
import com.example.a_java.dto.LendingListDTO;
import com.example.a_java.dto.LendingProcessDTO;
import com.example.a_java.entity.CustAccount;
import com.example.a_java.entity.LoanContract;
import com.example.a_java.entity.LoanDisbursement;
import com.example.a_java.entity.LoanApply;
import com.example.a_java.mapper.LoanContractMapper;
import com.example.a_java.mapper.LoanDisbursementMapper;
import com.example.a_java.mapper.LoanApplyMapper;
import com.example.a_java.service.CustAccountService;
import com.example.a_java.service.LoanDisbursementService;
import com.example.a_java.service.SysDictService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 放款记录Service实现�? */
@Service
public class LoanDisbursementServiceImpl extends ServiceImpl<LoanDisbursementMapper, LoanDisbursement> implements LoanDisbursementService {

    private static final Logger log = LoggerFactory.getLogger(LoanDisbursementServiceImpl.class);

    @Autowired
    private LoanContractMapper loanContractMapper;
    
    @Autowired
    private LoanApplyMapper loanApplyMapper;
    
    @Autowired
    private CustAccountService custAccountService;
    
    @Autowired
    private SysDictService sysDictService;
    
    @Override
    public IPage<LoanDisbursement> getLendingList(LendingListDTO queryDTO) {
        Page<LoanDisbursement> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        LambdaQueryWrapper<LoanDisbursement> queryWrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        if (StringUtils.isNotBlank(queryDTO.getContractNo())) {
            // 根据合同编号查询，需要先查询合同ID
            LambdaQueryWrapper<LoanContract> contractQueryWrapper = new LambdaQueryWrapper<>();
            contractQueryWrapper.like(LoanContract::getContractNo, queryDTO.getContractNo());
            List<LoanContract> contracts = loanContractMapper.selectList(contractQueryWrapper);
            List<Long> contractIds = new ArrayList<>();
            for (LoanContract contract : contracts) {
                contractIds.add(contract.getContractId());
            }
            
            if (!contractIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getContractId, contractIds);
            } else {
                // 没有找到匹配的合同，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(queryDTO.getLoanNo())) {
            // 根据贷款编号查询，需要先查询申请ID
            LambdaQueryWrapper<LoanApply> applyQueryWrapper = new LambdaQueryWrapper<>();
            applyQueryWrapper.like(LoanApply::getApplyNo, queryDTO.getLoanNo());
            List<LoanApply> applies = loanApplyMapper.selectList(applyQueryWrapper);
            List<Long> applyIds = new ArrayList<>();
            for (LoanApply apply : applies) {
                applyIds.add(apply.getApplyId());
            }
            
            if (!applyIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getApplyId, applyIds);
            } else {
                // 没有找到匹配的申请，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(queryDTO.getCustomerName())) {
            queryWrapper.like(LoanDisbursement::getCustomerName, queryDTO.getCustomerName());
        }
        
        if (StringUtils.isNotBlank(queryDTO.getCustomerPhone())) {
            queryWrapper.like(LoanDisbursement::getCustomerPhone, queryDTO.getCustomerPhone());
        }
        
        // 处理status参数 - 修复status字段映射问题
        if (StringUtils.isNotBlank(queryDTO.getStatus())) {
            try {
                Integer statusInt = Integer.parseInt(queryDTO.getStatus());
                queryWrapper.eq(LoanDisbursement::getDisburseStatus, statusInt);
            } catch (NumberFormatException e) {
                // 如果无法解析为数字，忽略此条件
                log.warn("Invalid status value: {}", queryDTO.getStatus());
            }
        }
        
        // 处理日期范围
        if (queryDTO.getStartDate() != null) {
            queryWrapper.ge(LoanDisbursement::getCreateTime, queryDTO.getStartDate() + " 00:00:00");
        }
        
        if (queryDTO.getEndDate() != null) {
            queryWrapper.le(LoanDisbursement::getCreateTime, queryDTO.getEndDate() + " 23:59:59");
        }
        
        // 添加排序
        if (queryDTO.getOrderBy() != null) {
            String orderBy = queryDTO.getOrderBy();
            String orderType = queryDTO.getOrderType();
            
            if ("createTime".equals(orderBy)) {
                if ("asc".equals(orderType)) {
                    queryWrapper.orderByAsc(LoanDisbursement::getCreateTime);
                } else {
                    queryWrapper.orderByDesc(LoanDisbursement::getCreateTime);
                }
            } else if ("disburseTime".equals(orderBy)) {
                if ("asc".equals(orderType)) {
                    queryWrapper.orderByAsc(LoanDisbursement::getDisburseTime);
                } else {
                    queryWrapper.orderByDesc(LoanDisbursement::getDisburseTime);
                }
            } else if ("amount".equals(orderBy)) {
                if ("asc".equals(orderType)) {
                    queryWrapper.orderByAsc(LoanDisbursement::getAmount);
                } else {
                    queryWrapper.orderByDesc(LoanDisbursement::getAmount);
                }
            } else {
                // 默认按创建时间降序
                queryWrapper.orderByDesc(LoanDisbursement::getCreateTime);
            }
        } else {
            // 默认按创建时间降序
            queryWrapper.orderByDesc(LoanDisbursement::getCreateTime);
        }
        
        // 只查询未删除的记录
        queryWrapper.eq(LoanDisbursement::getIsDeleted, 0);
        
        return this.page(page, queryWrapper);
    }

    @Override
    public LendingDetailVO getLendingDetail(Long disbursementId) {
        // 查询放款记录
        LoanDisbursement disbursement = this.getById(disbursementId);
        if (disbursement == null) {
            return null;
        }
        
        // 查询合同信息
        LoanContract contract = loanContractMapper.selectById(disbursement.getContractId());
        if (contract == null) {
            return null;
        }
        
        // 转换为VO
        LendingDetailVO detailVO = new LendingDetailVO();
        BeanUtils.copyProperties(disbursement, detailVO);
        
        // 设置合同相关信息
        detailVO.setContractNo(contract.getContractNo());
        detailVO.setLoanTerm(contract.getLoanTerm());
        detailVO.setLoanPurpose(contract.getLoanPurpose());
        detailVO.setRepayMethod(String.valueOf(contract.getRepayMethod()));
        detailVO.setInterestRate(contract.getInterestRate());
        
        // 设置还款方式名称
        String repayMethodName = "等额本息"; // 默认值
        try {
            // 尝试获取字典标签，如果方法不存在则使用默认值
            // 根据具体实现修改此处代码
            // repayMethodName = sysDictService.getDictLabel("repay_method", detailVO.getRepayMethod());
            switch (Integer.parseInt(detailVO.getRepayMethod())) {
                case 1: repayMethodName = "等额本息"; break;
                case 2: repayMethodName = "等额本金"; break;
                case 3: repayMethodName = "先息后本"; break;
                case 4: repayMethodName = "一次性还本付息"; break;
                default: repayMethodName = "未知";
            }
        } catch (Exception e) {
            // 忽略异常，使用默认值
        }
        detailVO.setRepayMethodName(repayMethodName);
        
        // 设置放款状态名称
        detailVO.setStatus(String.valueOf(disbursement.getDisburseStatus()));
        String statusName;
        switch (disbursement.getDisburseStatus()) {
            case 10:
                statusName = "待审批";
                break;
            case 20:
                statusName = "处理中";
                break;
            case 30:
                statusName = "放款成功";
                break;
            case 40:
                statusName = "放款失败";
                break;
            default:
                statusName = "未知状态";
        }
        detailVO.setStatusName(statusName);
        
        // TODO: 还款计划查询，设置首次还款日期和最后还款日期
        return detailVO;
    }

    @Override
    public void exportLendingList(LendingListDTO queryDTO, HttpServletResponse response) {
        // 查询数据
        queryDTO.setPageNum(1);
        queryDTO.setPageSize(Integer.MAX_VALUE); // 导出全部数据
        IPage<LoanDisbursement> page = this.getLendingList(queryDTO);
        List<LoanDisbursement> list = page.getRecords();
        
        // TODO: 实现导出Excel的逻辑
        // 此处需要引入相关Excel处理库，如POI或EasyExcel
        
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = "放款记录_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        
        try {
            // 使用Excel工具库导出数据
            // ExcelUtil.exportExcel(list, "放款记录", LoanDisbursement.class, response.getOutputStream());
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw new RuntimeException("导出Excel失败", e);
        }
    }

    @Override
    public IPage<LoanDisbursement> getPendingList(String contractNo, String loanNo, String customerName, Integer pageNum, Integer pageSize) {
        Page<LoanDisbursement> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<LoanDisbursement> queryWrapper = new LambdaQueryWrapper<>();
        
        // 只查询审批通过（处理中）的放款记录
        queryWrapper.eq(LoanDisbursement::getDisburseStatus, 20);
        
        // 构建查询条件
        if (StringUtils.isNotBlank(contractNo)) {
            // 根据合同编号查询，需要先查询合同ID
            LambdaQueryWrapper<LoanContract> contractQueryWrapper = new LambdaQueryWrapper<>();
            contractQueryWrapper.like(LoanContract::getContractNo, contractNo);
            List<LoanContract> contracts = loanContractMapper.selectList(contractQueryWrapper);
            List<Long> contractIds = new ArrayList<>();
            for (LoanContract contract : contracts) {
                contractIds.add(contract.getContractId());
            }
            
            if (!contractIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getContractId, contractIds);
            } else {
                // 没有找到匹配的合同，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(loanNo)) {
            // 根据贷款编号查询，需要先查询申请ID
            LambdaQueryWrapper<LoanApply> applyQueryWrapper = new LambdaQueryWrapper<>();
            applyQueryWrapper.like(LoanApply::getApplyNo, loanNo);
            List<LoanApply> applies = loanApplyMapper.selectList(applyQueryWrapper);
            List<Long> applyIds = new ArrayList<>();
            for (LoanApply apply : applies) {
                applyIds.add(apply.getApplyId());
            }
            
            if (!applyIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getApplyId, applyIds);
            } else {
                // 没有找到匹配的申请，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(customerName)) {
            queryWrapper.like(LoanDisbursement::getCustomerName, customerName);
        }
        
        // 默认按申请时间降序
        queryWrapper.orderByDesc(LoanDisbursement::getCreateTime);
        
        return this.page(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long applyLending(LendingApplyDTO applyDTO, Long userId) {
        // 1. 查询合同信息
        LoanContract contract = loanContractMapper.selectById(applyDTO.getContractId());
        if (contract == null) {
            throw new RuntimeException("合同不存在");
        }
        
        // 2. 检查合同状态是否为已生效
        if (contract.getContractStatus() != 30) {
            throw new RuntimeException("合同状态不是已生效状态");
        }
        
        // 3. 检查是否已有处理中的放款申请
        LambdaQueryWrapper<LoanDisbursement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LoanDisbursement::getContractId, contract.getContractId())
                .in(LoanDisbursement::getDisburseStatus, Arrays.asList(10, 20)); // 待审批或处理中
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new RuntimeException("已存在处理中的放款申请");
        }
        
        // 4. 查询贷款申请信息
        LoanApply loanApply = loanApplyMapper.selectById(contract.getApplyId());
        if (loanApply == null) {
            throw new RuntimeException("贷款申请不存在");
        }
        
        // 5. 校验放款金额
        if (applyDTO.getAmount() == null || applyDTO.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("放款金额不能为零或负数");
        }
        
        if (applyDTO.getAmount().compareTo(contract.getLoanAmount()) > 0) {
            throw new RuntimeException("放款金额超出批准金额");
        }
        
        // 6. 创建放款记录
        LoanDisbursement disbursement = new LoanDisbursement();
        disbursement.setContractId(contract.getContractId());
        disbursement.setApplyId(loanApply.getApplyId());
        disbursement.setCustomerId(contract.getCustId());
        
        // 获取客户姓名和手机号
        // 假设LoanApply类中有获取客户姓名和手机号的方法
        // 如果不存在，需要修改为获取这些信息的正确方法
        // 例如，可能需要从其他表中查询
        String customerName = "";
        String customerPhone = "";
        // 根据实际情况获取这些信息
        disbursement.setCustomerName(customerName);
        disbursement.setCustomerPhone(customerPhone);
        
        disbursement.setAmount(applyDTO.getAmount());
        
        // 解析计划放款日期
        if (StringUtils.isNotBlank(applyDTO.getDisburseDate())) {
            disbursement.setDisburseDate(LocalDate.parse(applyDTO.getDisburseDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        
        disbursement.setBankName(applyDTO.getBankName());
        disbursement.setBankAccount(applyDTO.getBankAccount());
        disbursement.setAccountName(applyDTO.getAccountName());
        disbursement.setDisburseStatus(10); // 待审批
        disbursement.setRemark(applyDTO.getRemark());
        disbursement.setCreateBy(userId);
        
        this.save(disbursement);
        
        return disbursement.getDisbursementId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processLending(LendingProcessDTO processDTO, Long userId) {
        // 1. 查询放款记录是否存在
        LoanDisbursement disbursement = this.getById(processDTO.getDisbursementId());
        if (disbursement == null) {
            throw new RuntimeException("放款记录不存在");
        }
        
        // 2. 检查放款状态是否为处理中
        if (disbursement.getDisburseStatus() != 20) {
            throw new RuntimeException("放款状态不允许修改");
        }
        
        // 3. 检查流水号是否已存在
        if (StringUtils.isNotBlank(processDTO.getTransactionNo())) {
            // 验证交易流水号是否重复
            LambdaQueryWrapper<LoanDisbursement> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LoanDisbursement::getTransactionNo, processDTO.getTransactionNo())
                    .ne(LoanDisbursement::getDisbursementId, processDTO.getDisbursementId());
            long count = this.count(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("流水号已存在");
            }
        }
        
        // 4. 更新放款记录
        LoanDisbursement updateDisbursement = new LoanDisbursement();
        updateDisbursement.setDisbursementId(processDTO.getDisbursementId());
        
        // 设置放款时间
        updateDisbursement.setDisburseTime(processDTO.getDisburseTime());
        
        updateDisbursement.setTransactionNo(processDTO.getTransactionNo());
        updateDisbursement.setDisburseStatus(processDTO.getStatus());
        updateDisbursement.setUpdateBy(userId);
        
        // 如果是放款失败，记录失败原因
        if (processDTO.getStatus() == 40) {
            updateDisbursement.setFailReason(processDTO.getFailReason());
        }
        
        return this.updateById(updateDisbursement);
    }

    @Override
    public IPage<LoanDisbursement> getPendingApprovalList(String contractNo, String loanNo, String customerName, Integer pageNum, Integer pageSize) {
        Page<LoanDisbursement> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<LoanDisbursement> queryWrapper = new LambdaQueryWrapper<>();
        
        // 只查询待审批的放款记录
        queryWrapper.eq(LoanDisbursement::getDisburseStatus, 10);
        
        // 构建查询条件
        if (StringUtils.isNotBlank(contractNo)) {
            // 根据合同编号查询，需要先查询合同ID
            LambdaQueryWrapper<LoanContract> contractQueryWrapper = new LambdaQueryWrapper<>();
            contractQueryWrapper.like(LoanContract::getContractNo, contractNo);
            List<LoanContract> contracts = loanContractMapper.selectList(contractQueryWrapper);
            List<Long> contractIds = new ArrayList<>();
            for (LoanContract contract : contracts) {
                contractIds.add(contract.getContractId());
            }
            
            if (!contractIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getContractId, contractIds);
            } else {
                // 没有找到匹配的合同，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(loanNo)) {
            // 根据贷款编号查询，需要先查询申请ID
            LambdaQueryWrapper<LoanApply> applyQueryWrapper = new LambdaQueryWrapper<>();
            applyQueryWrapper.like(LoanApply::getApplyNo, loanNo);
            List<LoanApply> applies = loanApplyMapper.selectList(applyQueryWrapper);
            List<Long> applyIds = new ArrayList<>();
            for (LoanApply apply : applies) {
                applyIds.add(apply.getApplyId());
            }
            
            if (!applyIds.isEmpty()) {
                queryWrapper.in(LoanDisbursement::getApplyId, applyIds);
            } else {
                // 没有找到匹配的申请，返回空结果
                return new Page<>();
            }
        }
        
        if (StringUtils.isNotBlank(customerName)) {
            queryWrapper.like(LoanDisbursement::getCustomerName, customerName);
        }
        
        // 默认按申请时间降序
        queryWrapper.orderByDesc(LoanDisbursement::getCreateTime);
        
        return this.page(page, queryWrapper);
    }
} 


